<template>
  <div class="voice-clone-page">
    <!-- 上半部分：操作框 -->
    <div class="panel">
      <div class="panel-header">
        <div class="panel-tabs">
          <el-button class="tab-btn tab-btn--active" size="large">
            声音克隆
          </el-button>
          <el-button class="tab-btn" size="large" @click="handleGenerateAudio">
            文字转语音
          </el-button>
        </div>
      </div>
      
      <el-form label-width="120px" class="form">
        <el-form-item label="音色名称">
          <el-input v-model="form.name" placeholder="请输入音色名称，如：我的音色" />
        </el-form-item>
        <el-form-item label="上传原始音频">
          <input 
            ref="fileInputRef" 
            type="file" 
            accept=".mp3,.wav,.m4a,.aac,.flac,.ogg,.wma,.aiff,.au,.ra,.amr,.3gp" 
            @change="handleAudioFileSelect" 
            style="display:none" 
          />
          <el-button @click="triggerFileSelect">选择音频文件</el-button>
          <span v-if="audioFileName" class="file-name">{{ audioFileName }}</span>
        </el-form-item>
        <el-form-item v-if="audioPreviewUrl" label="音频预览">
          <audio :src="audioPreviewUrl" controls style="width: 100%"></audio>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :loading="submitting" @click="handleSubmit" class="submit-btn">
            提交音色
            <span class="points-text">30积分</span>
          </el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 下半部分：列表 -->
    <div class="panel">
      <div class="panel-header">
        <h3>我的音色</h3>
        <el-button 
          type="primary" 
          :icon="Refresh" 
          @click="handleRefresh"
          :loading="loadingList"
        >
          刷新
        </el-button>
      </div>
      <el-table :data="records" v-loading="loadingList" size="large">
        <el-table-column prop="id" label="ID" width="150" />
        <el-table-column prop="name" label="名称" min-width="200" />
        <el-table-column prop="status" label="状态" width="160" />
        <el-table-column prop="create_time" label="创建时间" width="220" />
        <el-table-column label="错误信息" width="250">
          <template #default="{ row }">
            <div v-if="row.error_msg" class="error-msg">
              <el-icon><Warning /></el-icon>
              <span>{{ row.error_msg }}</span>
            </div>
            <span v-else class="no-error">-</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="{ row }">
            <el-button 
              type="danger" 
              size="default" 
              :icon="Delete" 
              @click="handleDelete(row)"
              :loading="deletingId === row.id"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="pagination">
        <el-pagination
          background
          layout="prev, pager, next, jumper"
          :total="total"
          :page-size="pageSize"
          :current-page="page"
          @current-change="handlePageChange"
        />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElLoading, ElMessageBox } from 'element-plus'
import { Refresh, Delete, Warning } from '@element-plus/icons-vue'
import { apiRequest, API_CONFIG } from '@/config/api'

const router = useRouter()

const form = ref({
  name: ''
})
const fileInputRef = ref(null)
const audioFileName = ref('')
const audioPreviewUrl = ref('')
const uploadedFileId = ref('')
const submitting = ref(false)

const page = ref(1)
const pageSize = ref(10)
const total = ref(0)
const records = ref([])
const loadingList = ref(false)
const deletingId = ref(null)

function triggerFileSelect() {
  fileInputRef.value?.click()
}

async function handleAudioFileSelect(event) {
  const file = event.target.files?.[0]
  if (!file) return
  
  // 支持的音频格式列表
  const supportedAudioFormats = [
    'audio/mpeg', 'audio/mp3', 'audio/wav', 'audio/wave', 'audio/x-wav',
    'audio/m4a', 'audio/aac', 'audio/x-aac',
    'audio/flac', 'audio/x-flac', 'audio/ogg', 'audio/vorbis',
    'audio/x-ms-wma', 'audio/wma', 'audio/aiff', 'audio/x-aiff',
    'audio/basic', 'audio/x-au', 'audio/x-pn-realaudio', 'audio/amr',
    'audio/3gpp'
  ]
  
  // 支持的音频文件扩展名
  const supportedExtensions = [
    '.mp3', '.wav', '.m4a', '.aac', '.flac', '.ogg', '.wma', 
    '.aiff', '.au', '.ra', '.amr', '.3gp'
  ]
  
  // 检查文件类型和扩展名
  const fileExtension = '.' + file.name.split('.').pop().toLowerCase()
  const isValidType = file.type.startsWith('audio/')
  const isValidExtension = supportedExtensions.includes(fileExtension)
  const isValidMimeType = supportedAudioFormats.includes(file.type.toLowerCase())
  
  if (!isValidType && !isValidExtension && !isValidMimeType) {
    ElMessage.error('请选择支持的音频文件格式（MP3, WAV, M4A, AAC, FLAC, OGG, WMA, AIFF, AU, RA, AMR, 3GP）')
    return
  }
  
  audioFileName.value = file.name

  const loading = ElLoading.service({ lock: true, text: '上传音频中...', background: 'rgba(0,0,0,0.7)' })
  try {
    // 获取文件后缀名
    const fileExtension = file.name.split('.').pop().toLowerCase()
    
    // 1. 获取上传凭证，传递format参数
    const credentialResp = await apiRequest(API_CONFIG.ENDPOINTS.GET_UPLOAD_CREDENTIAL, { 
      method: 'GET',
      params: { format: fileExtension }
    })
    if (credentialResp.code !== 200 || !credentialResp.data) {
      throw new Error(credentialResp.message || '获取上传凭证失败')
    }
    const { uploadUrl, fileId } = credentialResp.data

    // 2. PUT 上传音频到对象存储
    const putResp = await fetch(uploadUrl, {
      method: 'PUT',
      body: file,
      headers: { 'Content-Type': file.type || 'audio/mpeg' }
    })
    if (!putResp.ok) throw new Error('音频上传失败')

    // 3. 设置本地预览与 fileId
    if (audioPreviewUrl.value) URL.revokeObjectURL(audioPreviewUrl.value)
    audioPreviewUrl.value = URL.createObjectURL(file)
    uploadedFileId.value = fileId
    ElMessage.success('音频上传成功')
  } catch (err) {
    console.error('音频上传失败:', err)
    ElMessage.error(err.message || '音频上传失败')
    // 重置
    uploadedFileId.value = ''
    audioPreviewUrl.value = ''
  } finally {
    loading.close()
    // 重置 input 的值，确保同名文件也能再次触发 change 事件
    if (fileInputRef.value) fileInputRef.value.value = ''
  }
}

async function handleSubmit() {
  // 提交前校验是否已登录（是否有 token）
  if (!localStorage.getItem('token')) {
    ElMessage.error('未登录或登录已过期')
    window.location.href = '/login'
    return
  }

  if (!form.value.name) {
    ElMessage.error('请填写音色名称')
    return
  }
  if (!uploadedFileId.value) {
    ElMessage.error('请先上传音频文件')
    return
  }
  submitting.value = true
  try {
    const resp = await apiRequest(API_CONFIG.ENDPOINTS.VOICE_CLONE_SUBMIT, {
      method: 'POST',
      body: JSON.stringify({
        originVoiceFileId: uploadedFileId.value,
        name: form.value.name
      })
    })
    if (resp.code === 200) {
      ElMessage.success('提交成功')
      // 清空表单和预览
      form.value.name = ''
      audioFileName.value = ''
      uploadedFileId.value = ''
      if (audioPreviewUrl.value) {
        URL.revokeObjectURL(audioPreviewUrl.value)
        audioPreviewUrl.value = ''
      }
      // 刷新列表
      fetchList()
    } else {
      ElMessage.error(resp.msg || '提交失败')
    }
  } finally {
    submitting.value = false
  }
}

async function fetchList() {
  loadingList.value = true
  try {
    const resp = await apiRequest(API_CONFIG.ENDPOINTS.VOICE_CLONE_LIST, {
      method: 'GET',
      params: { page: page.value, pageSize: pageSize.value }
    })
    if (resp.code === 200) {
      records.value = Array.isArray(resp.data?.list) ? resp.data.list : []
      total.value = Number(resp.data?.total || 0)
    }
  } finally {
    loadingList.value = false
  }
}

function handlePageChange(p) {
  page.value = p
  fetchList()
}

// 刷新列表
function handleRefresh() {
  fetchList()
}

// 跳转到生成音频页面
function handleGenerateAudio() {
  router.push('/voice/tts')
}

// 删除音色
async function handleDelete(row) {
  try {
    await ElMessageBox.confirm(
      `确定要删除音色"${row.name}"吗？此操作不可恢复。`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
    
    deletingId.value = row.id
    try {
      const resp = await apiRequest(API_CONFIG.ENDPOINTS.VOICE_CLONE_DELETE, {
        method: 'DELETE',
        body: JSON.stringify({ taskId: row.id })
      })
      
      if (resp.code === 200) {
        ElMessage.success('删除成功')
        // 刷新列表
        fetchList()
      } else {
        ElMessage.error(resp.msg || '删除失败')
      }
    } catch (err) {
      console.error('删除失败:', err)
      ElMessage.error(err.message || '删除失败')
    }
  } catch {
    // 用户取消删除
  } finally {
    deletingId.value = null
  }
}

onMounted(() => {
  fetchList()
})
</script>

<style scoped>
.voice-clone-page {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.panel {
  background: #23232a;
  border: 1px solid #2a2a2a;
  border-radius: 12px;
  padding: 16px;
  color: #fff;
}

.panel h2, .panel h3 {
  margin: 0;
  color: #fff;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.panel-tabs {
  display: flex;
  gap: 12px;
}

/* 顶部“声音克隆 / 文字转语音”Tab 样式，避免两个按钮都看起来像激活态 */
.panel-tabs :deep(.tab-btn) {
  background: transparent !important;
  border: 1px solid #409eff !important;
  color: #409eff !important;
  font-weight: 500;
}

.panel-tabs :deep(.tab-btn--active) {
  background: #409eff !important;
  color: #fff !important;
}

.panel-header h3 {
  margin: 0;
  color: #fff;
}

.form { max-width: 720px; }
.file-name { margin-left: 12px; color: #9aa0a6; }
.audio-format-tips {
  margin-top: 8px;
  padding: 8px 12px;
  background: #1a1a1a;
  border-radius: 6px;
  border: 1px solid #2a2a2a;
}
.audio-format-tips small {
  color: #67c23a;
  font-size: 12px;
  line-height: 1.4;
}

.pagination { margin-top: 12px; text-align: right; }

/* 仅作用于本页：输入框黑色、下拉暗色、按钮蓝色，且去除白色边线 */
:deep(.el-input__wrapper),
:deep(.el-select .el-input__wrapper) {
  background: #0f0f12 !important; /* 黑色输入框外层 */
  color: #fff !important;
  border-radius: 8px !important;
  border: none !important;
  box-shadow: none !important;
}
:deep(.el-input__inner),
:deep(.el-textarea__inner) {
  color: #fff !important;
  background: #0f0f12 !important; /* 黑色输入区域 */
  border: none !important;
  box-shadow: none !important;
}
:deep(.el-input__inner::placeholder),
:deep(.el-textarea__inner::placeholder) {
  color: rgba(255,255,255,0.55) !important;
}

/* 下拉面板暗色 */
:deep(.el-select-dropdown) {
  background: #1b1b20 !important;
  color: #fff !important;
  border: none !important;
  box-shadow: 0 8px 20px rgba(0,0,0,0.6) !important;
}
:deep(.el-select-dropdown__item) {
  color: #fff !important;
}
:deep(.el-select-dropdown__item:hover) {
  background: #2a2a30 !important;
  color: #fff !important;
}
:deep(.el-select-dropdown__item.selected) {
  background: #409eff !important;
  color: #fff !important;
}

/* 表格无边框与分隔线 */
:deep(.el-table),
:deep(.el-table th),
:deep(.el-table td) {
  background: #23232a !important;
  color: #fff !important;
  border: none !important;
  font-size: 16px !important;
}

:deep(.el-table th) {
  font-size: 18px !important;
  font-weight: 600 !important;
  padding: 20px 0 !important;
}

:deep(.el-table td) {
  font-size: 16px !important;
  padding: 18px 0 !important;
}

:deep(.el-table .cell) {
  font-size: 16px !important;
  line-height: 1.6 !important;
}
:deep(.el-table__inner-wrapper::before),
:deep(.el-table--border .el-table__inner-wrapper::after),
:deep(.el-table--group::after),
:deep(.el-table--border::after),
:deep(.el-table--border::before) {
  background-color: transparent !important;
}
:deep(.el-table td),
:deep(.el-table th.is-leaf) { border-bottom: none !important; }
:deep(.el-table--border .el-table__cell) { border-right: none !important; }

/* 分页去白边：按钮、页码、跳转输入 */
:deep(.el-pagination) {
  background: #23232a !important;
  padding: 8px 12px;
  border-radius: 8px;
  border: none !important;
}
:deep(.el-pagination .btn-prev),
:deep(.el-pagination .btn-next),
:deep(.el-pagination button) {
  background: #1b1b1f !important;
  color: #fff !important;
  border: none !important;
  box-shadow: none !important;
}
:deep(.el-pagination .el-pager li) {
  background: #1b1b1f !important;
  color: #fff !important;
  border: none !important;
  box-shadow: none !important;
}
:deep(.el-pagination .el-pager li.is-active) {
  background: #409eff !important;
  color: #fff !important;
}
:deep(.el-pagination .el-pagination__jump .el-input__wrapper) {
  background: #0f0f12 !important; /* 跳转输入黑色 */
  border: none !important;
  box-shadow: none !important;
}
:deep(.el-pagination .el-input__wrapper.is-focus) { box-shadow: none !important; }
:deep(.el-pagination .el-input__inner) { color: #fff !important; }

/* 按钮蓝色 */
:deep(.el-button),
:deep(.el-button--primary) {
  background: #409eff !important;
  border: none !important;
  color: #fff !important;
}

/* 提交按钮积分样式 */
.submit-btn {
  position: relative;
  padding-right: 80px !important;

  .points-text {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 12px;
    opacity: 1;
    padding-left: 12px;
    border-left: 1px solid rgba(255, 255, 255, 0.5);
  }
}
:deep(.el-button:hover),
:deep(.el-button--primary:hover) {
  background: #337ecc !important;
  color: #fff !important;
}
:deep(.el-button.is-disabled),
:deep(.el-button.is-disabled:hover) {
  background: #3a3a40 !important;
  color: #9aa0a6 !important;
  border: none !important;
}


/* 错误信息样式 */
.error-msg {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #f56c6c;
  font-size: 12px;
  background: rgba(245, 108, 108, 0.1);
  padding: 4px 8px;
  border-radius: 4px;
  border: 1px solid rgba(245, 108, 108, 0.2);
  word-break: break-all;
  line-height: 1.4;
}

.no-error {
  color: #909399;
  font-size: 12px;
}
</style>

